package com.night.ibatis;

import com.night.annotation.Component;
import com.night.annotation.Mapper;
import com.night.context.AnnotationConfigApplicationContext;
import com.night.context.BeanDefinition;
import com.night.context.BeanFactoryPostProcessor;
import com.night.utils.ClassUtils;

import java.lang.reflect.Modifier;
import java.util.Set;

/**
 * @Author: chen yang
 * @Date: 2024/12/13 14:50
 */
@Component
public class MapperBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(AnnotationConfigApplicationContext beanFactory) throws RuntimeException {
        Set<String> beanClassNames = beanFactory.getBeanClassNames();

        for (String beanClassName : beanClassNames) {
            Class<?> clazz;
            try {
                clazz = Class.forName(beanClassName);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }

            // 只处理 interface
            if (!Modifier.isAbstract(clazz.getModifiers())) {
                continue;
            }

            Mapper mapper = ClassUtils.findAnnotation(clazz, Mapper.class);

            if (mapper == null) {
                continue;
            }

            String beanName = ClassUtils.getBeanName(clazz);

            Object instance = MapperProxyFactory.getMapper(clazz);
            var def = new BeanDefinition(beanName, clazz, instance.getClass().getConstructors()[0], Integer.MAX_VALUE, false,
                    // named init / destroy method:
                    null, null,
                    // init method:
                    null,
                    // destroy method:
                    null);
            def.setInstance(instance);
            beanFactory.registerBeanDefinition(beanName, def);
        }
    }
}
